﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using BLL.Services.Authors;
using BLL.Services.Books;
using BLL.Services.Categories;
using FB2Library;

namespace Grabber
{
    class Program
    {
        private static ICategoriesService _categoriesService;

        private static IAuthorsService _authorsService;

        static void Main(string[] args)
        {
            var bookPath = ConfigurationManager.AppSettings["BookPath"];
            var uploadPath = ConfigurationManager.AppSettings["UploadPath"];
            var connectionString = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;
            var files = Directory.GetFiles(bookPath);
            var bookService = new BooksService(new BooksCollection(connectionString));
            _categoriesService = new CategoriesService(new CategoryCollection(connectionString));
            _authorsService = new AuthorsService(new AuthorsCollection(connectionString));
            foreach (var file in files)
            {
                try
                {
                    FB2File book = new FB2File();
                    book.Load(XDocument.Load("file://" + file), false);
                    var newBook = new Book(){UserId = 1};
                    if (bookService.GetAllBooks.FirstOrDefault(x => x.Name == book.TitleInfo.BookTitle.Text.Trim()) != null)
                    {
                        continue;
                    }
                    var categoryIds = new List<int>();
                    try
                    {
                        foreach (var categoryName in book.TitleInfo.Genres)
                        {
                            categoryIds.Add(GetGenreId(categoryName.Genre));
                        }
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Error" + string.Join(", ", book.TitleInfo.Genres.Select(x => x.Genre)));
                    }

                    newBook.CategoryIds = categoryIds.ToArray();
                    if (book.TitleInfo.Annotation != null)
                    {
                        newBook.ShortContent = book.TitleInfo.Annotation.ToString();
                    }
                    else
                    {
                        continue;
                    }
                    newBook.DateOfPublish = DateTime.Now;
                    newBook.Name = book.TitleInfo.BookTitle.Text.Trim();
                    var authors = new List<int>();
                    foreach (var authorElement in book.TitleInfo.BookAuthors)
                    {
                        if (authorElement.FirstName.Text.Trim().Replace(".", "").Length <= 1 || authorElement.LastName.Text.Trim().Replace(".", "").Length < 1)
                            continue;
                        authors.Add(GetAuthorId(authorElement.FirstName.Text.Trim(), authorElement.LastName.Text.Trim(), authorElement.MiddleName.Text.Trim()));
                    }
                    if (authors.Count == 0)
                        continue;
                    newBook.AuthorIds = authors.ToArray();
                    if (book.TitleInfo.Cover == null || !book.TitleInfo.Cover.HasImages())
                    {
                        continue;
                    }

                    var imageHref = book.TitleInfo.Cover.CoverpageImages.FirstOrDefault().HRef.Replace("#", "");
                    if (book.Images.Count == 0)
                        continue;
                    var image = book.Images.FirstOrDefault(x => x.Key == imageHref).Value.BinaryData;

                    var name = Guid.NewGuid() + (imageHref.ToLower().Contains(".jpg") ? ".jpg" : ".png");
                    using (var stream = new FileStream(uploadPath + name, FileMode.Create))
                    {
                        stream.Write(image, 0, image.Length);
                        stream.Close();
                    }
                    newBook.Avatar = name;

                    try
                    {
                        var fileName = Guid.NewGuid() + ".zip";
                        var bookName = new Regex(@"\W").Replace(newBook.Name, "_");
                        Directory.CreateDirectory(bookPath + bookName);
                        File.Copy(file, bookPath + bookName + "/" + bookName + ".fb2", true);
                        ZipFile.CreateFromDirectory(bookPath + bookName, uploadPath + fileName);
                        newBook.FileName = fileName;
                        bookService.Create(newBook);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("File error");
                    }
                    Console.WriteLine(newBook.Name);
                }
                catch (Exception)
                {
                    Console.WriteLine(file);
                }
               
            }
        }

        private static int GetGenreId(string genreName)
        {
            var value = new Grabber.Categories().GetCategoryName(genreName);
            var category = _categoriesService.GetAllCategories.FirstOrDefault(x => x.Name == value);
            if (category==null)
            {
                _categoriesService.Create(new Category(){Name = value});
            }
            return _categoriesService.GetAllCategories.FirstOrDefault(x => x.Name == value).CategoryId;
        }

        private static int GetAuthorId(string firstName, string lastName, string middleName)
        {
            var authorId = _authorsService.GetAuthorId(firstName, lastName, middleName);
            if (authorId == 0)
            {
                _authorsService.Create(new Author() { FirstName = firstName, LastName = lastName });
            }
            return _authorsService.GetAuthorId(firstName, lastName, middleName);
        }
    }
}
